package com.yeskery.nut.websocket;

import com.yeskery.nut.annotation.websocket.WebSocket;
import com.yeskery.nut.bean.ApplicationContext;
import com.yeskery.nut.bean.BeanPriorityPostProcessor;
import com.yeskery.nut.bean.FactoryBeanRegister;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

/**
 * WebSocket的Bean后置处理器
 * @author sprout
 * @version 1.0
 * 2023-04-15 21:37
 */
public class WebSocketBeanPriorityPostProcessor implements WebSocketConfigurationCollector, BeanPriorityPostProcessor {

    /** 日志对象 */
    public static final Logger logger = Logger.getLogger(WebSocketBeanPriorityPostProcessor.class.getName());

    /** WebSocket配置集合 */
    private final List<WebSocketConfiguration> webSocketConfigurationList = new ArrayList<>();

    @Override
    public void process(Object bean, Class<?> beanClass, ApplicationContext applicationContext, FactoryBeanRegister factoryBeanRegister) {
        WebSocket webSocket = beanClass.getAnnotation(WebSocket.class);
        if (webSocket != null) {
            loadWebSocketServerEndpoint(bean, webSocket);
        }
    }

    @Override
    public Collection<WebSocketConfiguration> getWebSocketConfigurations() {
        return webSocketConfigurationList;
    }

    /**
     * 加载WebSocket服务端点
     * @param bean bean对象
     * @param webSocket WebSocket注解对象
     */
    private void loadWebSocketServerEndpoint(Object bean, WebSocket webSocket) {
        DefaultWebSocketConfiguration webSocketConfiguration = new DefaultWebSocketConfiguration();
        DefaultWebSocketServerConfigure webSocketServerConfigure = new DefaultWebSocketServerConfigure(webSocket.path());
        webSocketConfiguration.setWebSocketServerConfigure(webSocketServerConfigure);

        AnnotationWebSocketHandler annotationWebSocketHandler = new AnnotationWebSocketHandler();
        WebSocketHandler webSocketHandler = (WebSocketHandler) Proxy.newProxyInstance(annotationWebSocketHandler.getClass().getClassLoader(),
                annotationWebSocketHandler.getClass().getInterfaces(), new AnnotationWebSocketHandlerInvocationHandler(bean));
        webSocketConfiguration.setWebSocketHandler(webSocketHandler);
        webSocketConfigurationList.add(webSocketConfiguration);

        logger.info("WebSocket Path[" + (webSocketServerConfigure.isDynamic() ? "$" : "")
                + webSocketServerConfigure.getPathMetadata().getOriginalPath()
                + "], Handler Class[" + bean.getClass().getName() + "]");
    }
}
